java自定义线程池执行器
我正在编写一个定制的ThreadPoolExecutor,具有以下额外功能:-
若线程数大于核心池大小但小于最大池大小,且队列未满且不存在理想线程,则为任务创建新线程
如果存在理想的线程,并且随着任务的到来,将该任务分配给队列,而不是将其添加到队列中
如果所有线程(最大池大小)都忙,则在新任务到来时,使用RejectionHandler的reject方法将它们添加到队列中
我已经重写了ThreadPoolExecutor version java 1.5的execute方法
新守则如下:-
public void execute(Runnable command) {
System.out.println(" Active Count: "+getActiveCount()+" PoolSize: "+getPoolSize()+" Idle Count: "+(getPoolSize()-getActiveCount())+" Queue Size: "+getQueue().size());
if (command == null)
throw new NullPointerException();
for (;;) {
if (runState != RUNNING) {
reject(command);
return;
}
if (poolSize < corePoolSize && addIfUnderCorePoolSize(command)) {
return;
}
if (runState == RUNNING && (getPoolSize()-getActiveCount() != 0) && workQueue.offer(command)) {
return;
}
int status = addIfUnderMaximumPoolSize(command);
if (status > 0) // created new thread
return;
if (status == 0) { // failed to create thread
reject(command);
return;
}
if (workQueue.offer(command))
return;
// Retry if created a new thread but it is busy with another task
}
}
遗留代码如下所示:-
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
for (;;) {
if (runState != RUNNING) {
reject(command);
return;
}
if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
return;
if (workQueue.offer(command))
return;
int status = addIfUnderMaximumPoolSize(command);
if (status > 0) // created new thread
return;
if (status == 0) { // failed to create thread
reject(command);
return;
}
// Retry if created a new thread but it is busy with another task
}
}
现在产生的问题是,当线程空闲时,它不会创建新线程,但它甚至不会将任务分配给这些线程,否则它会将它们添加到队列中,这是不需要的,因为我们不希望任务等待,但会尽快处理它,即使它需要创建新线程,但任务不允许等待
请帮我解决这个问题。谢谢
# 1 楼答案
就我对您描述的三个功能的了解而言,我认为使用ExectuorService将比您目前尝试的做得更多:一个
Executor
提供了管理终止的方法,以及可以产生未来跟踪一个或多个异步任务进度的方法,特别是:一,捕获的线程池:允许创建执行并行任务所需的任意多个线程。旧的可用线程将被重新用于新任务和固定线程池
二,固定线程池:提供具有固定线程数的池。如果某个线程不可用于该任务,则该任务将被放入队列中,等待其他任务结束
Check out this article for detail explanation and nice example.
# 2 楼答案
如果我理解了这个问题,我相信我已经找到了
ThreadPoolExecutor
默认行为的解决方案,我在这里的回答中显示了:基本上,您需要
LinkedBlockingQueue
让它始终为queue.offer(...)
返回false,这将在必要时向池中添加额外的线程。如果池已经达到最大线程数,并且它们都很忙,那么将调用RejectedExecutionHandler
。然后是处理程序将put(...)
处理到队列中看到我的代码了吗